import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
import LoginVue from '../views/Login/login.vue'
import LayoutVue from '../views/layout/layout.vue'
import { userInfoApi } from "@/api";
import { useUserStore } from "@/store/userStore";
import { generateRoutes } from '@/utils/menu'

const routes: RouteRecordRaw[] = [
  { path: '/login', component: LoginVue },
  {
    path: '/', component: LayoutVue, redirect: '/home', children: [
      { path: '/home', component: () => import('../views/homepage/homepage.vue') }
    ]
  }
];

// 创建 路由 实现
const router = createRouter({
  history: createWebHashHistory(),
  routes
})
router.beforeEach((to, from, next) => {
  // hook 必须要在函数里面调用(pinia文档里面有强调的)
  const userStore = useUserStore()
  let token = localStorage.getItem('token')
  // 什么情况下需要获取用户的信息？当用户信息没有的时候并且token存在
  // 如何判断？把用户的信息放在 store 中，就可以知道到底有没有了
  if (token && userStore.menus.length === 0) {
    userInfoApi().then(res => {
      if (res.code == 200) {
        // 把用户的信息放在 store 中
        userStore.name = res.data.username;
        userStore.menus = res.data.menus;
        // 用户信息回来之后，后端的用户权限也一起回来了，我们需要根据后端返回的数据，生成
        // ums/admin
        // pms/addProduct
        // 类似上面的两级的路由
        // 1级路由的path就是1级菜单的name属性
        // 2级路由的path就是2级菜单的name属性
        // 但是不能直接使用菜单数据，菜单不是所有的路由
        // 只能重新生成一个新的数据，用来生成路由
        let data = generateRoutes(res.data.menus);
        // 根据上面的父子关系，生成 动态路由
        // 最终要的路由结构是下面的结构
        // router.addRoute({
        //   path:'/ums',
        //   component: 组件,
        //   children: [
        //     { path: 'admin' ,component: 子组件1},
        //     { path: 'role' ,component: 子组件2},
        //   ]
        // });
        // 1组件路由就是data数组里面的每个1级对象
        data.forEach(p => {
          // 生成1级路由
          const route: RouteRecordRaw = {
            path: '/' + p.name,
            name: p.name,
            meta: {
              title: p.title
            },
            // 无论1级路由怎么变化，外层都是不变，只是二级路由在右侧变化
            component: LayoutVue,
            children: p.children.map(c => ({
              path: c.name,
              name: c.name,
              meta: {
                title: c.title
              },
              // 二级路由对应的组件是变化的，不能写死的，要有一定规律来添加
              // 我们约定好，在views里面使用1级路由的name作为文件夹分开管理不同的组件子级组件
              // 约定以自己的name作为文件名，作为一个.vue文件
              component: () => import(`../views/${p.name}/${c.name}.vue`)
            }))
          }
          // addRoute 方法，在添加路由的时候，其实不是同步的执行的，也是一个异步的过程
          // 添加路由到路由生效，也是需要时间的
          router.addRoute(route);
        })
        // getRoutes 返回所有的路由配置
        // console.log(router.getRoutes())
        // 解决方案是，让next不是直接放行，而是再次进行跳转
        next(to.fullPath); // next传递参数，会导致 beforeEach会被重新执行
      }
    })
  } else if (token && to.path == '/login') {
    // 如果是已经登录的情况，并且还想要访问登录页，不让用户访问
    // 回退到之前的页面
    next(from.fullPath);
  }
  else {
    next();
  }

})

export default router;